/*
 * Copyright (c) GoKeep by gokeep.org. 2022-2023. All rights reserved
 */
package org.gokeep.communication.message;

import com.google.protobuf.ByteString;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.gokeep.common.config.GlobalConfig;
import org.gokeep.communication.proto.CommandProto;
import org.gokeep.communication.proto.MessageProto;

import java.util.function.Function;

/**
 * 消息构建器
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class MessageBuilder {

    private MessageProto.Message message;

    /**
     * 设置message对象
     * @param message
     * @return
     */
    public static  MessageBuilder with(MessageProto.Message message) {
        MessageBuilder builder = new MessageBuilder();
        builder.message = message;
        return builder;
    }

    /**
     * 构建MessageBuilder
     * @return
     */
    public static MessageBuilder builder() {
        return new MessageBuilder();
    }

    /**
     * 获取详细对象
     * @param message
     * @return
     */
    public MessageBuilder message(MessageProto.Message message) {
        this.message = message;
        return this;
    }

    /**
     * 获取消息构建对象
     * @return
     */
    public MessageProto.Message.Builder getMessageBuilder() {
        return this.message.toBuilder();
    }

    /**
     * 获取消息指令
     * @return
     */
    public CommandProto.CommandEnum getCommand() {
        return this.message.getCommand();
    }

    /**
     * 获取token
     * @return
     */
    public String getToken() {
        return this.message.getToken();
    }

    /**
     * 是否为非法协议头
     * @return
     */
    public boolean isLegalProtocol() {
        return GlobalConfig.MESSAGE_PROTOCOL_HEAD == this.message.getProtocol();
    }

    /**
     * 获取版本
     * @return
     */
    public int getVersion() {
        return this.message.getVersion();
    }

    /**
     * 获取加密方式
     * @return
     */
    public MessageProto.EncryptEnum getEncrypt() {
        return this.message.getEncrypt();
    }

    /**
     * 获取序列号
     * @return
     */
    public long getSerializeNo() {
        return this.message.getSerializeNo();
    }

    /**
     * 获取数据内容
     * @return
     */
    public ByteString getData() {
        return this.message.getData();
    }

    /**
     * 获取数据体数组
     * @return
     */
    public byte[] getDataByteArray() {
        return this.message.getData().toByteArray();
    }

    /**
     * 函数式获取数据
     * @param function
     * @return
     * @param <T>
     */
    public <T> T getData(Function<ByteString, T> function) {
        return function.apply(this.message.getData());
    }


    /**
     * 初始化默认消息
     * @return
     */
    public MessageProto.Message.Builder initMessageBuilder(CommandProto.CommandEnum command, String token) {
        MessageProto.Message.Builder builder = MessageProto.Message.newBuilder();
        builder.setProtocol(GlobalConfig.MESSAGE_PROTOCOL_HEAD);
        builder.setVersion(GlobalConfig.MESSAGE_VERSION);
        builder.setEncrypt(MessageProto.EncryptEnum.RSA);
        builder.setCommand(command);
        builder.setToken(token);
        builder.setData(ByteString.EMPTY);
        return builder;
    }

    /**
     * 初始化消息，不设置token
     * @param command
     * @return
     */
    public MessageProto.Message.Builder initMessageBuilder(CommandProto.CommandEnum command) {
        return this.initMessageBuilder(command, "");
    }

    /**
     * 初始化消息
     * @param command
     * @param token
     * @return
     */
    public MessageProto.Message initMessage(CommandProto.CommandEnum command, String token) {
        return initMessageBuilder(command, token).build();
    }

    /**
     * 初始化消息
     * @param command
     * @return
     */
    public MessageProto.Message initMessage(CommandProto.CommandEnum command) {
        return initMessageBuilder(command).build();
    }
}